<!doctype html>
<html lang="zh_cn" itemscope itemtype="http://schema.org/Person">
<head>
            <meta charset="utf-8">
        <!-- Site Meta Data -->
        <title>[原创]iView Datepicker无法获取格式化的时间(默认带T和Z)</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta name="description" content="技术博客,涉及Java/PHP/Python/Javascript等,聊聊程序,聊聊生活,聊聊事实,聊聊育儿">
        <meta name="keywords" content="编码经验,技术分享,生活积累,实事评说">
        <meta name="author" content="布丁缘">

        <link rel="shortcut icon" href="">

        <link href='https://fonts.googleapis.com/css?family=Open+Sans:400,600,700' rel='stylesheet' type='text/css'>
        <!-- Style Meta Data -->
        <link rel="stylesheet" href="https://www.ddkiss.com/theme/css/style.css" type="text/css"/>
        <link rel="stylesheet" href="https://www.ddkiss.com/theme/css/pygments.css" type="text/css"/>

        <!-- Feed Meta Data -->
            <link href="https://www.ddkiss.com/feeds/all.atom.xml" type="application/atom+xml" rel="alternate"
                  title="一个程序员的简单生活 ATOM Feed"/>


    <meta name="keywords" content="iview,datepicker,date,json,axios">
    <link rel="stylesheet" href="//dn-coding-net-public-file.qbox.me/Coding-Comments/v0.1.0/default.css">
</head>

<body>
<!-- Sidebar -->
<aside>
    <center><h1><a href="/" style="color:#fff"><img id="avatar" src="/images/avatar.jpg"></a></h1></center>
        <p>一个程序员的简单生活</p>
    <br>
    <nav class="nav">
        <ul class="list-bare">
                <li><a class="nav__link" href="https://www.ddkiss.com/category/chang-yong-ji-qiao.html">常用技巧</a></li>
                <li><a class="nav__link" href="https://www.ddkiss.com/category/kai-fa-huan-jing.html">开发环境</a></li>
                <li><a class="nav__link" href="https://www.ddkiss.com/category/sheng-huo-dian-di.html">生活点滴</a></li>

                <li><a class="nav__link" href="/pages/books.html">书单</a></li>
                <li><a class="nav__link" href="/pages/movies.html">影单</a></li>
                <li><a class="nav__link" href="/pages/downloads.html">下载</a></li>
                <li><a class="nav__link" href="/pages/about.html">关于我</a></li>


        </ul>
    </nav>


    <form>
      <input type="text"  id="bdcsMain"/>
    </form>

</aside>

<!-- Content -->
<article>
  <main>
    <nav>
      <a href="/">首页</a>
      <a href="/archives.html">归档</a>
      <a href="/categories.html">分类</a>
      <a href="/tags.html">标签</a>
      <a href="/pages/about.html">关于我</a>
    </nav>
  </main>
    <section id="content">
        <article>
            <h2 class="post_title post_detail"><a href="https://www.ddkiss.com/archives/73.html" rel="bookmark"
                                                  title="Permalink to [原创]iView Datepicker无法获取格式化的时间(默认带T和Z)">[原创]iView Datepicker无法获取格式化的时间(默认带T和Z)</a></h2>

            <div class="post_list">
                <span>作者：</span><a href="https://www.ddkiss.com/author/bu-ding-yuan.html">布丁缘</a>
                <span class="post_category">分类：<a href="https://www.ddkiss.com/category/kai-fa-huan-jing.html" rel="bookmark"
                                               title="Permalink to 开发环境">开发环境</a></span>
                <span class="post_date">  时间：2017-10-24 17:28:00</span>

            </div>
            <div class="entry-content blog-post">
                <p>使用 iview 的 Datepicker 控件过程中发现，前端获取绑定数据时取得的是 Date 类型，后台接收的的结果是诸如<code>2017-10-24T09:27:37.827Z</code>这样的串。而数据库里存的格式都是类似于 <code>2017-10-24 09:27:37</code> 这样的。怎么办？</p>
<h2>一、原因分析</h2>
<p>最先想到的是 Datepicker 源码里处理 Date 类型时引起的。查看了源码，发现它只在显示界面上时进行了时间格式化，获取对象时并未处理。从 vue devtools里看到值显示的是 date 类型，比如<code>Thu Sep 07 2017 08:00:00 GMT+0800 (CST)</code>,这是GMT格式表示的。所以，原因不在这里。</p>
<p>我们是通过<a href="https://www.npmjs.com/package/axios">axios</a>来完成ajax请求的。代码如下：</p>
<div class="highlight"><pre><span></span>axios.post(&#39;/user&#39;, params)).then(function(response){});
</pre></div>


<p>看了下源码，发现了axios处理post参数时的代码中对date类型进行了处理，代码为</p>
<table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="kd">function</span> <span class="nx">isDate</span><span class="p">(</span><span class="nx">val</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">return</span> <span class="nx">toString</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">val</span><span class="p">)</span> <span class="o">===</span> <span class="s1">&#39;[object Date]&#39;</span><span class="p">;</span>
<span class="p">}</span>

<span class="c1">//..... 此处省略其他代码</span>

<span class="nx">utils</span><span class="p">.</span><span class="nx">forEach</span><span class="p">(</span><span class="nx">val</span><span class="p">,</span> <span class="kd">function</span> <span class="nx">parseValue</span><span class="p">(</span><span class="nx">v</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">if</span> <span class="p">(</span><span class="nx">utils</span><span class="p">.</span><span class="nx">isDate</span><span class="p">(</span><span class="nx">v</span><span class="p">))</span> <span class="p">{</span>
    <span class="nx">v</span> <span class="o">=</span> <span class="nx">v</span><span class="p">.</span><span class="nx">toISOString</span><span class="p">();</span>
  <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">utils</span><span class="p">.</span><span class="nx">isObject</span><span class="p">(</span><span class="nx">v</span><span class="p">))</span> <span class="p">{</span>
    <span class="nx">v</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">(</span><span class="nx">v</span><span class="p">);</span>
  <span class="p">}</span>
  <span class="nx">parts</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">encode</span><span class="p">(</span><span class="nx">key</span><span class="p">)</span> <span class="o">+</span> <span class="s1">&#39;=&#39;</span> <span class="o">+</span> <span class="nx">encode</span><span class="p">(</span><span class="nx">v</span><span class="p">));</span>
<span class="p">});</span>
</pre></div>
</td></tr></table>

<p>那<code>toISOString()</code>方法是干嘛的？toISOString() 方法可以使用ISO标准将 Date 对象转换为字符串。该标准称为 ISO-8601，格式为: <code>YYYY-MM-DDTHH:mm:ss.sssZ</code>。注意，这个方法IE8及其以前的版本都不支持。OK，到此为止找到了问题的原因。</p>
<h2>二、解决办法</h2>
<p>这种问题一般分为前端和后端处理。先说下后端怎么处理，比如Java中。转载请注明出处 www.ddkiss.com</p>
<h3>方法一：Java版实现方法，手动转换</h3>
<table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1">//格式类似于 &quot;2017-07-02T16:00:00.000Z&quot;</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="n">String</span> <span class="nf">convertTime</span><span class="o">(</span><span class="n">String</span> <span class="n">time</span><span class="o">)</span> <span class="o">{</span>
  <span class="n">SimpleDateFormat</span> <span class="n">sf</span> <span class="o">=</span> <span class="k">new</span> <span class="n">SimpleDateFormat</span><span class="o">(</span><span class="s">&quot;yyyy-MM-dd&#39;T&#39;HH:mm:ss.SSS&#39;Z&#39;&quot;</span><span class="o">);</span>
  <span class="n">sf</span><span class="o">.</span><span class="na">setTimeZone</span><span class="o">(</span><span class="n">TimeZone</span><span class="o">.</span><span class="na">getTimeZone</span><span class="o">(</span><span class="s">&quot;UTC&quot;</span><span class="o">));</span>
  <span class="n">SimpleDateFormat</span> <span class="n">toSf</span> <span class="o">=</span> <span class="k">new</span> <span class="n">SimpleDateFormat</span><span class="o">(</span><span class="s">&quot;yyyy-MM-dd&quot;</span><span class="o">);</span>
  <span class="k">try</span> <span class="o">{</span>
    <span class="k">return</span> <span class="n">toSf</span><span class="o">.</span><span class="na">format</span><span class="o">(</span><span class="n">sf</span><span class="o">.</span><span class="na">parse</span><span class="o">(</span><span class="n">time</span><span class="o">));</span>
  <span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="n">ParseException</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span>
    <span class="k">return</span> <span class="kc">null</span><span class="o">;</span>
  <span class="o">}</span>
<span class="o">}</span>
</pre></div>
</td></tr></table>

<h3>方法二：Axios提交Post请求之前将参数转为字符串</h3>
<p>首先想到的是<code>JSON.stringify()</code>,没想到，结果居然和axios默认的处理一样。怎么办？javascript怎么处理的呢？</p>
<div class="highlight"><pre><span></span>Uncaught ReferenceError: dateFormat is not defined
    at Date.toJSON (eval at save (http://localhost), &lt;anonymous&gt;:1:39)
    at JSON.stringify (&lt;anonymous&gt;)
</pre></div>


<p>从这里可以看出，默认情况下处理Date类型是调用了<code>Date.toJSON()</code>。所以，我们可以这么做，重写到原型方法。</p>
<table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="kd">function</span> <span class="nx">dateFormat</span><span class="p">(</span><span class="nx">date</span><span class="p">,</span> <span class="nx">fmt</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="kc">null</span> <span class="o">==</span> <span class="nx">date</span> <span class="o">||</span> <span class="kc">undefined</span> <span class="o">==</span> <span class="nx">date</span><span class="p">)</span> <span class="p">{</span>
      <span class="k">return</span> <span class="s1">&#39;&#39;</span><span class="p">;</span>
    <span class="p">}</span>
    <span class="kd">var</span> <span class="nx">o</span> <span class="o">=</span> <span class="p">{</span>
        <span class="s2">&quot;M+&quot;</span><span class="o">:</span> <span class="nx">date</span><span class="p">.</span><span class="nx">getMonth</span><span class="p">()</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="c1">//月份</span>
        <span class="s2">&quot;d+&quot;</span><span class="o">:</span> <span class="nx">date</span><span class="p">.</span><span class="nx">getDate</span><span class="p">(),</span> <span class="c1">//日</span>
        <span class="s2">&quot;h+&quot;</span><span class="o">:</span> <span class="nx">date</span><span class="p">.</span><span class="nx">getHours</span><span class="p">(),</span> <span class="c1">//小时</span>
        <span class="s2">&quot;m+&quot;</span><span class="o">:</span> <span class="nx">date</span><span class="p">.</span><span class="nx">getMinutes</span><span class="p">(),</span> <span class="c1">//分</span>
        <span class="s2">&quot;s+&quot;</span><span class="o">:</span> <span class="nx">date</span><span class="p">.</span><span class="nx">getSeconds</span><span class="p">(),</span> <span class="c1">//秒</span>
        <span class="s2">&quot;S&quot;</span><span class="o">:</span> <span class="nx">date</span><span class="p">.</span><span class="nx">getMilliseconds</span><span class="p">()</span> <span class="c1">//毫秒</span>
    <span class="p">};</span>
    <span class="k">if</span> <span class="p">(</span><span class="sr">/(y+)/</span><span class="p">.</span><span class="nx">test</span><span class="p">(</span><span class="nx">fmt</span><span class="p">)){</span>
      <span class="nx">fmt</span> <span class="o">=</span> <span class="nx">fmt</span><span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="nb">RegExp</span><span class="p">.</span><span class="nx">$1</span><span class="p">,</span> <span class="p">(</span><span class="nx">date</span><span class="p">.</span><span class="nx">getFullYear</span><span class="p">()</span> <span class="o">+</span> <span class="s2">&quot;&quot;</span><span class="p">).</span><span class="nx">substr</span><span class="p">(</span><span class="mi">4</span> <span class="o">-</span> <span class="nb">RegExp</span><span class="p">.</span><span class="nx">$1</span><span class="p">.</span><span class="nx">length</span><span class="p">));</span>
      <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">k</span> <span class="k">in</span> <span class="nx">o</span><span class="p">){</span>
        <span class="k">if</span> <span class="p">(</span><span class="k">new</span> <span class="nb">RegExp</span><span class="p">(</span><span class="s2">&quot;(&quot;</span> <span class="o">+</span> <span class="nx">k</span> <span class="o">+</span> <span class="s2">&quot;)&quot;</span><span class="p">).</span><span class="nx">test</span><span class="p">(</span><span class="nx">fmt</span><span class="p">)){</span>
          <span class="nx">fmt</span> <span class="o">=</span> <span class="nx">fmt</span><span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="nb">RegExp</span><span class="p">.</span><span class="nx">$1</span><span class="p">,</span> <span class="p">(</span><span class="nb">RegExp</span><span class="p">.</span><span class="nx">$1</span><span class="p">.</span><span class="nx">length</span> <span class="o">==</span> <span class="mi">1</span><span class="p">)</span> <span class="o">?</span> <span class="p">(</span><span class="nx">o</span><span class="p">[</span><span class="nx">k</span><span class="p">])</span>
                <span class="o">:</span> <span class="p">((</span><span class="s2">&quot;00&quot;</span> <span class="o">+</span> <span class="nx">o</span><span class="p">[</span><span class="nx">k</span><span class="p">]).</span><span class="nx">substr</span><span class="p">((</span><span class="s2">&quot;&quot;</span> <span class="o">+</span> <span class="nx">o</span><span class="p">[</span><span class="nx">k</span><span class="p">]).</span><span class="nx">length</span><span class="p">)));</span>          
        <span class="p">}</span>        
      <span class="p">}</span>
    <span class="p">}</span>
    <span class="k">return</span> <span class="nx">fmt</span><span class="p">;</span>
<span class="p">};</span>

<span class="nb">Date</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">toJSON</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
  <span class="k">return</span> <span class="nx">dateFormat</span><span class="p">(</span><span class="k">this</span><span class="p">,</span><span class="s1">&#39;yyyy-MM-dd&#39;</span><span class="p">)</span>
<span class="p">};</span>
</pre></div>
</td></tr></table>

<p>就这么简单，引入了上面的代码后再调用<code>JSON.stringify()</code>后格式就成我们想要的了。</p>
<h3>方法三：将参数传入Axios前手工转换</h3>
<p>这里用到了<a href="http://momentjs.cn/">moment</a>,使用起来也很简单，代码如下</p>
<table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="nx">moment</span><span class="p">().</span><span class="nx">format</span><span class="p">(</span><span class="s1">&#39;yyyy-MM-dd&#39;</span><span class="p">)</span>
</pre></div>
</td></tr></table>

<h2>三、总结</h2>
<p>个人比较推荐修改 <code>JSON.toJSON</code>方法， 遇到包含Date类型字段的对象可以先变成字符串后ajax传递给后端，免去了针对单个字段的逐个hack.</p>
            </div>
            <div class="post_list">
              <div><span>Tags : </span>
                          <span><a href="https://www.ddkiss.com/tag/vue.html">#vue, </a></span>
                          <span><a href="https://www.ddkiss.com/tag/iview.html">#iview, </a></span>
                          <span><a href="https://www.ddkiss.com/tag/javascript.html">#javascript, </a></span>
              </div>
            </div>
        </article>
        <div id="container"></div>
        <script type="text/javascript" src="//dn-coding-net-public-file.qbox.me/Coding-Comments/v0.1.0/gitment.min.js"></script>
        <script>
            var gitment = new Gitment({
              owner: 'whusl',
              repo: 'BlogComments',
              oauth: {
                client_id: '621866266817529fba46681653017809',
                client_secret: '14188411740b12ae52159cee9b586bf85cd54125',
              },
            })
            document.getElementById('container').appendChild(gitment.render())
          </script>
    </section>
</article>

<!-- Footer -->
    <footer>
        <p> &copy;2017-2020&nbsp;<a href="http://www.miitbeian.gov.cn/" target="_blank">鄂ICP备17020200号</a>
          Blog powered by <a href="http://getpelican.com/">Pelican</a>
        </p>
    </footer>

    <!-- Analytics -->
    <script>
      var _hmt = _hmt || [];
      (function() {
        var hm = document.createElement("script");
        hm.src = "https://hm.baidu.com/hm.js?88c55edaf311dbacac56a16316b04c8b";
        var s = document.getElementsByTagName("script")[0];
        s.parentNode.insertBefore(hm, s);
      })();
    </script>

<script type="text/javascript">(function(){document.write(unescape('%3Cdiv id="bdcs"%3E%3C/div%3E'));var bdcs = document.createElement('script');bdcs.type = 'text/javascript';bdcs.async = true;bdcs.src = 'http://znsv.baidu.com/customer_search/api/js?sid=14490611060029767912' + '&plate_url=' + encodeURIComponent(window.location.href) + '&t=' + Math.ceil(new Date()/3600000);var s = document.getElementsByTagName('script')[0];s.parentNode.insertBefore(bdcs, s);})();</script>

</body>
</html>